package com.pdool.game.logic.service;

import com.pdool.common.constants.Constant;
import com.pdool.common.constants.ErrorCode;
import com.pdool.common.dict.CardTreeDictVo;
import com.pdool.common.dict.DropOutVo;
import com.pdool.common.entity.CardGroupEntity;
import com.pdool.common.entity.RoleNumInfoEntity;
import com.pdool.common.exception.ErrorException;
import com.pdool.common.msg.card.MakeGroupReq;
import com.pdool.common.msg.card.UpdateCardGroupReq;
import com.pdool.game.cache.CardGroupCache;
import com.pdool.game.core.res.ResOp;
import com.pdool.game.dict.BasePropConfig;
import com.pdool.game.dict.CardTreeConfig;
import com.pdool.game.dict.DropOutConfig;
import com.pdool.game.logic.domain.entity.vo.CardGroupVo;
import com.pdool.game.logic.enums.NumTypeEnum;
import com.pdool.game.util.DropUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 卡组处理器
 */
@Service
public class CardGroupService {
    @Resource
    CardGroupCache cardGroupCache;
    @Resource
    RoleService roleService;
    @Resource
    CardTreeConfig cardTreeConfig;
    @Resource
    BasePropConfig basePropConfig;
    @Resource
    DropOutConfig dropOutConfig;

    public  Map<Integer, CardGroupVo> allCardGroup(long roleId){
        Map<Integer, CardGroupVo> allCardGroupMap = cardGroupCache.getAllCardGroup(roleId);
        return allCardGroupMap;
    }

    public void updateCardGroup(Map<Integer, CardGroupVo> allCardGroup, CardGroupVo group) {
        cardGroupCache.updateCardGroup(allCardGroup, group);
    }

    public CardGroupVo getCardGroup(long roleId, int groupIndex) {
        Map<Integer, CardGroupVo> allCardGroupMap = cardGroupCache.getAllCardGroup(roleId);
        CardGroupVo cardGroupVo = allCardGroupMap.get(groupIndex);
        return cardGroupVo;
    }


    public void makeGroup(Long roleId, MakeGroupReq makeGroupReq) {
        int groupIndex = makeGroupReq.getGroupIndex();
        List<Integer> groupList = makeGroupReq.getCardIdList();
        Set<Integer> groupCardSet = new HashSet<>(groupList);
        if (groupCardSet.size() != groupList.size()) {
            throw new ErrorException(ErrorCode.CARD_GROUP_SAME_CARD);
        }
        int maxCount = Integer.parseInt(basePropConfig.getByKey(Constant.PROP_GROUP_MAX_COUNT).getValue());
        if (groupCardSet.size() > maxCount) {
            throw new ErrorException(ErrorCode.CARD_GROUP_TOO_MANY);
        }
        //  todo 检查组规则
        //  1、检查是否有这些卡牌
        //  2、检查传递的参数中是否有重复的
        //  3、检查卡规则
        //  4、保存卡牌
        Map<Integer, CardGroupVo> allCardGroup = cardGroupCache.getAllCardGroup(roleId);
        CardGroupEntity cardGroupEntity = new CardGroupEntity();
        cardGroupEntity.setGroupIndex(groupIndex);
        cardGroupEntity.setRoleId(roleId);
        cardGroupEntity.setGroupName(makeGroupReq.getGroupName());

        CardGroupVo orDefault = allCardGroup.getOrDefault(groupIndex, new CardGroupVo(cardGroupEntity));
        orDefault.getCardGroupList().addAll(groupList);
        cardGroupCache.updateCardGroup(allCardGroup, orDefault);
    }

    public void getCardTreeReward(long roleId, int lv) {
        RoleNumInfoEntity roleNumInfo = roleService.getRoleNumInfo(roleId, NumTypeEnum.CARD_TREE_EXP);

        String rewardLv = String.valueOf(lv);
        //  检查是否等级达到
        CardTreeDictVo cardTreeDictVo = cardTreeConfig.getDataMap().get(lv);
        if (cardTreeDictVo.getExp() > roleNumInfo.getNum()) {
            throw new ErrorException(ErrorCode.CARD_TREE_LV_NO_ENOUGH);
        }
        //  检查是否已经领奖
        String extend = roleNumInfo.getExtend();
        if (StringUtils.hasText(extend)) {
            String[] split = extend.split(Constant.SPLIT_SEMICOLON);
            for (String s : split) {
                if (rewardLv.equals(s)) {
                    throw new ErrorException(ErrorCode.CARD_TREE_HAS_GET);

                }
            }
        }
        ResOp resOp = new ResOp(roleId);

        String drop = cardTreeDictVo.getDrop();
        if (StringUtils.hasText(drop)) {
            DropOutVo byKey = dropOutConfig.getByKey(drop);
            String s = DropUtil.calcDrop(byKey.getWeightObjs());
            resOp.add(s);
        }
        String reward = cardTreeDictVo.getReward();
        resOp.add(reward);
        resOp.op();

        roleService.updateRoleNumExtend(roleId, NumTypeEnum.CARD_TREE_EXP, extend + Constant.SPLIT_SEMICOLON + rewardLv);
    }

    public void addCard2Group(Long roleId, UpdateCardGroupReq req) {
        List<Integer> cardListList = req.getCardListList();

        Set<Integer> cardSet = new HashSet<>(cardListList);
        if (cardSet.size() != cardListList.size()) {
            throw new ErrorException(ErrorCode.CARD_GROUP_SAME_CARD);
        }

        int groupIndex = req.getGroupIndex();

        Map<Integer, CardGroupVo> allCardGroup = cardGroupCache.getAllCardGroup(roleId);
        if (!allCardGroup.containsKey(groupIndex)) {
            throw new ErrorException(ErrorCode.CARD_GROUP_NOT_EXIST);
        }
        CardGroupVo cardGroupVo = allCardGroup.get(groupIndex);

//        boolean disjoint = Collections.disjoint(cardSet, cardGroupVo.getCardGroupList());
//        if (disjoint) {
//            throw new ErrorException(ErrorCode.CARD_GROUP_SAME_CARD);
//        }
        cardGroupVo.getCardGroupList().clear();
        cardGroupVo.getCardGroupList().addAll(cardListList);
        cardGroupCache.updateCardGroup(allCardGroup, cardGroupVo);

        allCardGroup.put(groupIndex, cardGroupVo);

    }


}
